<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <!-- 
    v-text 声明式的指令版本实现
   -->
   <!-- 
   目标：一旦data中的name发生变化之后 标记了v-text的p标签的文本内容会立刻得到更新
   实现指令的核心：不管是指令也好还是插值表达式也好 它们都是数据和视图之间建立关联的‘标识’
   所以本质就是通过一定的手段找到符合标识的dom元素 然后把数据放上去 每当数据发生变化 就重新
   执行一遍放置数据的操作
   实现步骤：
    1. 先通过标识查找把数据放到对应的dom上显示出来
    2. 数据变化之后再次执行将最新的值放到对应的dom上 (数据变化之后再次执行compile函数即可)
   -->
  <div id="app">
    <p v-text="name"></p>
    <div v-text="name"></div>
    <p v-text="age"></p>
  </div>
   
  <script>
    let data = {
      name: '柴柴老师',
      age: 29
    }
    // 把data中的属性变成响应式的
    Object.keys(data).forEach((key) => {
      defineReactive(data, key, data[key])
    })
    function defineReactive(data, key, value) {
      // 进行转换操作
      Object.defineProperty(data, key, {
        get() {
          console.log('您访问了属性', key)
          return value
        },
        set(newValue) {
          // set函数的执行 不会自动判断俩次修改的值是否相等
          // 显然如果相等 不应该执行变化的逻辑
          if (newValue === value) {
            return
          }
          console.log('您修改了属性', key)
          value = newValue
          // 这里我们把最新的值 反映到视图中  这里是关键的位置
          // 核心：操作dom  就是通过操作dom api 把最新的值设置上去
          compile()
        }
      })
    }
    // 1.通过标识查找把数据放到对应的dom上显示出来
    function compile() {
      let app = document.getElementById('app')
      // 拿到所有节点
      const childNodes = app.childNodes // 所有类型的节点包括文本节点和标签节点
      console.log(childNodes)
      // 刷选出来目标节点 -> p
      childNodes.forEach(node => {
        console.log(node.nodeType)
        if (node.nodeType === 1) {
          // 这里拿到的是标签节点
          console.log(node)
          // 刷选v-text属性 p id class (v-text)
          // 拿到所有的标签属性
          const attrs = node.attributes
          console.log(attrs)
          Array.from(attrs).forEach(attr => {
            console.log(attr)
            const nodeName = attr.nodeName
            const nodeValue = attr.nodeValue
            console.log(nodeName, nodeValue)
            // nodeName  -> v-text  就是我们需要查找的标识
            // nodeValue -> name    data中对应数据的key
            // 把data中的数据 放到满足标识的dom上
            if (nodeName === 'v-text') {
              console.log('设置值', node)
              node.innerText = data[nodeValue]
            }
          })
        }
      })
    }
    compile()
  </script>

  
</body>

</html>